/**
 * Light-commons Project
 * http://light-commons.googlecode.com
 * Copyright (C) 2008 Jason Green
 * email: guileen@gmail.com
 *
 * License: Apache License 2.0 
 * (http://www.apache.org/licenses/LICENSE-2.0)
 *
 */
package org.lightcommons.template.freemarker;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;

import org.lightcommons.resource.Resource;
import org.lightcommons.resource.ResourceLoader;
import org.lightcommons.template.AbstractTemplateFactory;
import org.lightcommons.template.Template;

import freemarker.cache.TemplateLoader;
import freemarker.template.Configuration;

/**
 * @author gl
 * @since Jun 16, 2008
 */
public class FreeMarkerFactory extends AbstractTemplateFactory{

	private final Configuration configuration;
	
	/**
	 * 
	 */
	public FreeMarkerFactory() {
		this(new Configuration());
	}
	
	/**
	 * @param configuration
	 */
	public FreeMarkerFactory(Configuration configuration) {
		super();
		this.configuration = configuration;
	}

	/**
	 * @return the configuration
	 */
	public Configuration getConfiguration() {
		return configuration;
	}

	@Override
	public void initResourceLoader(ResourceLoader loader) {
		configuration.setTemplateLoader(new FreemarkerLoader(loader));
	}
	
	@Override
	public Template compileSource(String path, String source) throws IOException {
		return new FreeMakerFacade(new freemarker.template.Template(path,new StringReader(source),configuration));
	}

	private static class FreemarkerLoader implements TemplateLoader{
		private ResourceLoader loader;
		
		public FreemarkerLoader(ResourceLoader loader) {
			super();
			this.loader = loader;
		}

		public void closeTemplateSource(Object input) throws IOException {
			try{
				((InputStream)input).close();
			}catch(Exception e){
			}
		}

		public Object findTemplateSource(String path) throws IOException {
			Resource resource = loader.getResource(path);
			if(resource!=null)
				return resource.getInputStream();
			return null;
		}

		public long getLastModified(Object input) {
			return 0;
		}

		public Reader getReader(Object in, String encoding) throws IOException {
			return new InputStreamReader((InputStream) in,encoding);
		}
		
	}

}
